// ------------------------------------------------------------------------------------------
// Licensed by Interprise Solutions.
// http://www.InterpriseSolutions.com
// For details on this license please visit  the product homepage at the URL above.
// THE ABOVE NOTICE MUST REMAIN INTACT.
// ------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using InterpriseSuiteEcommerceControls.Validators;
using InterpriseSuiteEcommerceCommon;
using InterpriseSuiteEcommerceCommon.InterpriseIntegration;
using System.Drawing.Design;
using InterpriseSuiteEcommerceCommon.DTO;

namespace InterpriseSuiteEcommerceControls
{
    public class ShippingMethodControl : BaseFormFieldControl
    {

        #region Variable Declaration

        private const string HIDDEN_FIELD_FALSE_VALUE = "0";
        private const String HIDDEN_FIELD_TRUE_VALUE = "1";
        private const string RENDER_REGISTRATION = "RenderRegistration";
        private const string RENDER_OPTIONS_ONLY = "RenderOptionsOnly";
        private const string SKIP_SHIPPING = "SkipShipping";
        private const string SHOW_REFRESH_LINK = "ShowRefreshLink";
        private const string SHIPPING_METHOD_TEMP_ATTRIBUTE = "sm";
        private const string SHIPPPING_METHOD_REQUIRED_ERROR_MESSAGE = "ShippingMethodRequiredErrorMessage";

        private Table _template = null;
        private HtmlInputHidden _hdfShippingMethod = null;
        private HtmlInputHidden _hdfFreight = null;
        private HtmlInputHidden _hdfFreightCalculation = null;
        private TableRow _loadingRow = null;
        private TableRow _contentRow = null;
        private Panel _pnlContent = null;
        private Image _imgLoading = null;

        private ShippingMethodDTOCollection _availableShippingMethods = new ShippingMethodDTOCollection();
        private List<HtmlInputRadioButton> _shippingOptions = new List<HtmlInputRadioButton>();
        private Address _shippingAddress = null;

        #endregion

        #region Constructor

        public ShippingMethodControl()
        {
            _template = new Table();
            _hdfShippingMethod = new HtmlInputHidden();
            _hdfFreight = new HtmlInputHidden();
            _hdfFreightCalculation = new HtmlInputHidden();
            _imgLoading = new Image();
            _loadingRow = new TableRow();
            _contentRow = new TableRow();
            _pnlContent = new Panel();
             
            AssignClientReferenceIds();
            AddSampleShippingMethods();
        }

        private void AssignClientReferenceIds()
        {
            _hdfShippingMethod.ID = "ShippingMethod";
            _hdfFreight.ID = "Freight";
            _hdfFreightCalculation.ID = "FreightCalculation";
            _loadingRow.ID = "LoadingRow";
            _contentRow.ID = "ContentRow";
            _imgLoading.ID = "LoadingImage";
            _pnlContent.ID = "Content";
        }

        private void AddSampleShippingMethods()
        {
            if (DesignMode)
            {
                ShippingMethodDTO sample1 = new ShippingMethodDTO("Freight 1", "Freight 1 Description");
                sample1.Freight = 10M;
                sample1.FreightDisplay = "$ 10";
                sample1.FreightCurrencyCode = "USD";

                ShippingMethodDTO sample2 = new ShippingMethodDTO("Freight 2", "Freight 2 Description");
                sample2.Freight = 20M;
                sample2.FreightDisplay = "$ 20";
                sample2.FreightCurrencyCode = "USD";

                ShippingMethodDTO sample3 = new ShippingMethodDTO("Freight 3", "Freight 3 Description");
                sample3.Freight = 30M;
                sample3.FreightDisplay = "$ 30";
                sample3.FreightCurrencyCode = "USD";                

                _availableShippingMethods.Add(sample1);
                _availableShippingMethods.Add(sample2);
                _availableShippingMethods.Add(sample3);
            }
        }

        #endregion

        #region Properties

        [Browsable(true), Category(VALIDATORS_CATEGORY)]
        public string ShippingMethodRequiredErrorMessage
        {
            get
            {
                object savedValue = ViewState[SHIPPPING_METHOD_REQUIRED_ERROR_MESSAGE];
                if (null == savedValue) { return string.Empty; }

                return savedValue.ToString();
            }
            set
            {
                ViewState[SHIPPPING_METHOD_REQUIRED_ERROR_MESSAGE] = value;
            }
        }

        public string ShippingMethodCode
        {
            get 
            {
                return _hdfShippingMethod.Value;
            }
            set
            {
                _hdfShippingMethod.Value = value;
            }
        }

        public string Freight
        {
            get
            {
                return _hdfFreight.Value;
            }
            set
            {
                _hdfFreight.Value = value;
            }
        }

        public string FreightCalculation
        {
            get
            {
                return _hdfFreightCalculation.Value;
            }
            set
            {
                _hdfFreightCalculation.Value = value;
            }
        }

        [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)),
         DefaultValue(""),
         UrlProperty,
         Bindable(true)]
        public string LoadingImageUrl
        {
            get { return _imgLoading.ImageUrl; }
            set { _imgLoading.ImageUrl = value; }
        }

        public virtual ShippingMethodDTOCollection AvailableShippingMethods
        {
            get { return _availableShippingMethods; }
            set { _availableShippingMethods = value; }
        }

        protected List<HtmlInputRadioButton> ShippingOptions
        {
            get { return _shippingOptions; }
        }

        #endregion

        #region Methods

        [Browsable(true), Category(APPEARANCE_CATEGORY)]
        public bool SkipShipping
        {
            get
            {
                object booleanValue = ViewState[SKIP_SHIPPING];
                if (null == booleanValue) { return false; }

                return booleanValue is bool && (bool)booleanValue;
            }
            set
            {
                ViewState[SKIP_SHIPPING] = value;
                ChildControlsCreated = false;
            }
        }

        [Browsable(true), Category(APPEARANCE_CATEGORY)]
        public bool ShowRefreshLink
        {
            get
            {
                object booleanValue = ViewState[SHOW_REFRESH_LINK];
                if (null == booleanValue) { return true; }

                return booleanValue is bool && (bool)booleanValue;
            }
            set
            {
                ViewState[SHOW_REFRESH_LINK] = value;
                ChildControlsCreated = false;
            }
        }

        protected override void CreateChildControls()
        {
            if (this.SkipShipping) { return; }

            Controls.Add(_hdfShippingMethod);
            Controls.Add(_hdfFreight);
            Controls.Add(_hdfFreightCalculation);

            _template.Width = Unit.Percentage(100);

            Table tblShipping = new Table();

            FormFieldBuilder shippingBuilder = new FormFieldBuilder(tblShipping);

            for(int ctr=0; ctr< _availableShippingMethods.Count; ctr++)
            {
                ShippingMethodDTO shippingMethod = _availableShippingMethods[ctr];
                HtmlInputRadioButton option = new HtmlInputRadioButton();
                option.Checked = shippingMethod.IsDefault;
                option.ID = "ShippingMethod_" + ctr.ToString();
                option.Name = "ShippingMethod";
                option.Value = shippingMethod.Code;
                option.Attributes[SHIPPING_METHOD_TEMP_ATTRIBUTE] = shippingMethod.Code;
               
                LiteralControl display = 
                new LiteralControl(
                    string.Format(
                        "&nbsp; {0}&nbsp;{1}&nbsp;({2}) <br/>",
                        Security.HtmlEncode(shippingMethod.Description),
                        Security.HtmlEncode(shippingMethod.FreightDisplay),
                        Security.HtmlEncode(shippingMethod.FreightCurrencyCode)
                    )
                );

                _shippingOptions.Add(option);

                shippingBuilder.NewRow();
                shippingBuilder.AddCell(FormFieldBuilder.ALIGN_LEFT, Unit.Percentage(100), option, display);
                shippingBuilder.CommitRow();
            }

            tblShipping.Width = Unit.Percentage(100);

            _pnlContent.Controls.Add(tblShipping);

            _template.Width = Unit.Percentage(100);

            FormFieldBuilder builder = new FormFieldBuilder(_template);

            builder.CurrentRow = _loadingRow;
            builder.AddCell(FormFieldBuilder.ALIGN_CENTER, Unit.Percentage(100), _imgLoading);
            builder.CommitRow();

            builder.CurrentRow = _contentRow;

            _pnlContent.Height = this.Height;
            _pnlContent.Width = this.Width;

            if (this.ShowRefreshLink)
            {
                _loadingRow.Style["display"] = "none";
                _contentRow.Style["display"] = "";

                Control ctrlRefreshCommand = null;

                switch (this.RefreshCommandType)
                {
                    case RefreshCommandTypes.Link:
                        HyperLink lnk = new HyperLink();
                        lnk.NavigateUrl = "javascript:void(0);";
                        lnk.Text = this.RefreshCommandCaption;

                        ctrlRefreshCommand = lnk;
                        break;
                    case RefreshCommandTypes.Button:
                        HtmlInputButton btn = new HtmlInputButton();
                        btn.Value = this.RefreshCommandCaption;

                        ctrlRefreshCommand = btn;
                        break;
                }

                ctrlRefreshCommand.ID = "Refresh";

                Panel pnlRefresh = new Panel();
                pnlRefresh.Attributes["align"] = "center";

                pnlRefresh.Controls.Add(ctrlRefreshCommand);

                builder.AddCell(FormFieldBuilder.ALIGN_LEFT, Unit.Percentage(100), pnlRefresh, new LiteralControl("<br />"), _pnlContent);
                builder.CommitRow();
            }
            else
            {
                _loadingRow.Style["display"] = "";
                _contentRow.Style["display"] = "none";

                builder.AddCell(FormFieldBuilder.ALIGN_LEFT, Unit.Percentage(100), _pnlContent);
                builder.CommitRow();
            }

            Controls.Add(_template);
        }

        public enum RefreshCommandTypes
        {
            Link,
            Button
        }

        private const string REFRESH_COMMAND_TYPE = "RefreshCommandType";

        [Browsable(true), Category(VALIDATORS_CATEGORY)]
        public RefreshCommandTypes RefreshCommandType
        {
            get
            {
                object savedValue = ViewState[REFRESH_COMMAND_TYPE];

                if (null == savedValue || !(savedValue is RefreshCommandTypes))
                {
                    return RefreshCommandTypes.Link;
                }

                return (RefreshCommandTypes)savedValue;
            }
            set
            {
                ViewState[REFRESH_COMMAND_TYPE] = value;
            }
        }

        private const string REFRESH_COMMAND_CAPTION = "RefreshCommandCaption";

        [Browsable(true), Category(VALIDATORS_CATEGORY)]
        public string RefreshCommandCaption
        {
            get
            {
                object savedValue = ViewState[REFRESH_COMMAND_CAPTION];
                if (null == savedValue) { return string.Empty; }

                return savedValue.ToString();
            }
            set
            {
                ViewState[REFRESH_COMMAND_CAPTION] = value;
            }
        }

        public Address ShippingAddress
        {
            get { return _shippingAddress; }
            set { _shippingAddress = value; }
        }

        public override void RenderControl(HtmlTextWriter writer)
        {
            EnsureChildControls();

            base.RenderControl(writer);

            StringBuilder script = new StringBuilder();
            script.Append("<script type=\"text/javascript\" language=\"Javascript\" >\n");
            script.Append("$add_windowLoad(\n");
            script.Append(" function() { \n");

            script.AppendFormat("   var reg = ise.Controls.ShippingMethodController.registerControl('{0}');\n", this.ClientID);

            script.Append("   if(reg) {\n");

            if (this.SkipShipping)
            {
                script.AppendFormat("      reg.setIsSkipShipping({0});\n", true.ToString().ToLowerInvariant());
            }
            else
            {
                foreach (HtmlInputRadioButton option in this.ShippingOptions)
                {
                    script.AppendFormat("      reg.registerOption(new ise.Controls.ShippingMethodOption('{0}', '{1}', '{2}'));\n", option.ClientID, option.Attributes["sm"], option.Attributes["rt"]);
                    option.Attributes[SHIPPING_METHOD_TEMP_ATTRIBUTE] = string.Empty;
                }
                script.AppendLine();                
            }

            foreach (InputValidator validator in this.ProvideValidators())
            {
                script.AppendFormat("      reg.registerValidator({0});\n", validator.RenderInitialization());
            }

            if (null != this.ErrorSummaryControl)
            {
                script.AppendFormat("      reg.setValidationSummary({0});", this.ErrorSummaryControl.RenderInitialization());
                script.AppendLine();
            }

            if (null != _shippingAddress)
            {
                script.AppendFormat("      reg.requestShippingMethod('{0}');\n", _shippingAddress.AddressID);
            }
            
            script.Append("   }\n");

            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");

            writer.Write(script.ToString());
        }

        protected override List<InputValidator> ProvideValidators()
        {
            List<InputValidator> defaultValidators = new List<InputValidator>();

            defaultValidators.Add(MakeRequiredInputValidator(_hdfShippingMethod, this.ShippingMethodRequiredErrorMessage));

            return defaultValidators;
        }

        private void BuildDisplayBasedOnAvailableShippingMethods()
        {
        }

        #endregion

        #region Event Handlers
        #endregion

    }
}
